package com.guojing.jl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.guojing.jl.bean.Product;
import com.guojing.jl.dao.ProductDao;
import com.guojing.jl.dto.PageResult;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * ① ElasticsearchRestTemple 是 ElasticsearchOperations 的子类的子类
 * ② 在ES7.x以下的版本使用的是 ElasticsearchTemple， 7.x以上版本已弃用 ElasticsearchTemple，使用 ElasticsearchRestTemple替代
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringDataESSearchTest {

    @Autowired
    private ProductDao productDao;

    @Autowired
    private ElasticsearchOperations elasticsearchOperations;

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    /**
     * term 查询：使用 term查询时不会对关键字进行分词。
     * search(termQueryBuilder) 调用搜索方法，参数查询构建器对象
     */
    @Test
    public void termQuery(){

        // 关键字查询，查询性为“女"的所有记录
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("category", "手机");
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        nativeSearchQueryBuilder.withQuery(termQueryBuilder);

        NativeSearchQuery nativeSearchQuery = nativeSearchQueryBuilder.build();
        SearchHits<Product> search = this.elasticsearchOperations.search(nativeSearchQuery, Product.class, IndexCoordinates.of("product"/*索引名*/));
        Iterator<SearchHit<Product>> iterator = search.iterator();
        while (iterator.hasNext()){
            SearchHit<Product> next = iterator.next();
            Product content = next.getContent();
            System.out.println(content);
        }


        //以下方法已经过时
        /*TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", "小米");
        Iterable<Product> products = productDao.search(termQueryBuilder);
        for (Product product : products) {
            System.out.println(product);
        }*/
    }


    /**
     * term 查询加分页
     */
    @Test
    public void termQueryByPage() {
        //以下方法过时
        /*int currentPage= 0 ;
        int pageSize = 5;
        //设置查询分页
        PageRequest pageRequest = PageRequest.of(currentPage, pageSize);
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", "小米");

        Iterable<Product> products =
                productDao.search(termQueryBuilder,pageRequest);
        for (Product product : products) {
            System.out.println(product);
        }*/

        int currentPage= 0 ;
        int pageSize = 5;

        // 构建查询条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        BoolQueryBuilder filter = QueryBuilders.boolQuery();

        // 添加基本分词查询
//        if (StrUtil.isNotBlank(query.getTitle())) {
            filter.must(QueryBuilders.termQuery("category", "手机"));
//        }
//        if (StrUtil.isNotBlank(query.getImages())) {
//            filter.must(QueryBuilders.termQuery("images", "test"));
//        }
       /* if (StrUtil.isNotBlank(query.getOriginalFileName())) {
            filter.must(QueryBuilders.matchQuery("originalFileName", query.getOriginalFileName()));
        }*/
        /*if (query.getCreateStartTime() != null) {
            filter.must(QueryBuilders.rangeQuery("createTime").gte(query.getCreateStartTime() + " 00:00:00"));
        }
        if (query.getCreateEndTime() != null) {
            filter.must(QueryBuilders.rangeQuery("createTime").lte(query.getCreateEndTime() + " 23:59:59"));
        }*/
        /*if (StrUtil.isNotBlank(query.getKeywordFilterTxt())) {
            queryBuilder.withQuery(QueryBuilders.queryStringQuery(query.getKeywordFilterTxt()));
        }*/
        queryBuilder.withFilter(filter);
        queryBuilder.withSort(SortBuilders.fieldSort("id").order(SortOrder.DESC));
        queryBuilder.withPageable(PageRequest.of(currentPage, pageSize));

        NativeSearchQuery nativeSearchQuery = queryBuilder.build();
        /*nativeSearchQuery.addFields("id", "ossUploadRecord", "categories","originalFileName",
                "resultPath","summary","rversion","createUser","createTime","fileType",
                "Keyword1","Keyword2","Keyword3","Keyword4","Keyword5","Keyword6","Keyword7","Keyword8");*/
        // 使用ElasticsearchRestTemplate进行复杂查询
        SearchHits<Product> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery, Product.class);

        PageResult result = new PageResult();
        if (searchHits.getTotalHits() > 0) {
            List<Product> searchProductList = searchHits.stream().map(SearchHit::getContent).collect(Collectors.toList());

            result.setPageNo(currentPage);
            result.setPageSize(pageSize);
            result.setRows(searchProductList);
            result.setTotal(searchHits.getTotalHits());
            result.setPages((int) Math.ceil((double) result.getTotal() / pageSize));
        }

        System.out.println(JSONUtil.toJsonStr(result));
        return ;
    }

}
